#include "remotetcpsocket.h"
#ifdef EREMOTEPROTOCOL_QDEBUG
#include <QDebug>
#endif
RemoteTcpSocket::RemoteTcpSocket(QObject *parent) : QTcpSocket(parent)
  , m_readyReadVersion(true),m_readyReadSize(true)
{
    setSocketOption(QAbstractSocket::LowDelayOption, 1);
    connect(this, &QTcpSocket::readyRead, this, &RemoteTcpSocket::ReadData);
}

RemoteTcpSocket::~RemoteTcpSocket()
{

}

QByteArray RemoteTcpSocket::getVersion()
{
    return QByteArray(PROTECT_VERSION_STRING, PROTECT_VERSION_DATA_SIZE);
}

bool RemoteTcpSocket::sendVersion()
{
    return mustWrite(PROTECT_VERSION_STRING, PROTECT_VERSION_DATA_SIZE);
}

// 发送封装的数据包
bool RemoteTcpSocket::sendPacket(const QByteArray &pkt)
{
    int size = static_cast<int>(pkt.size());
    if(!mustWrite(static_cast<const char*>(static_cast<void*>(&size))))
    {
        return false;
    }
    if(!mustWrite(pkt.data()))
    {
        return false;
    }
    return true;
}

// true 发送成功 false 发送失败
///
/// \brief RemoteTcpSocket::mustWrite 确保数据完整发送，这个函数会阻塞发送数据。
/// \param data
/// \param len
/// \return true, 发送成功; false,发送失败
///
bool RemoteTcpSocket::mustWrite(const char *data, qint64 len)
{
    int sendSize = 0;
    const char* buff = reinterpret_cast<const char*>(data);
    while(sendSize < len)
    {
        qint64 ret = this->write(buff + sendSize, len-sendSize);
        if(ret == -1)
        {
#ifdef EREMOTEPROTOCOL_QDEBUG
            qDebug()<<"发送数据失败";
#endif
            return false;
        }
        sendSize += ret;
    }
    return true;
}

void RemoteTcpSocket::ReadData()
{
    if(sender() != this)
    {
#ifdef EREMOTEPROTOCOL_QDEBUG
        qCritical()<<"错误的sender";
#endif
        return;
    }

    while(this->bytesAvailable())
    {
#ifdef EREMOTEPROTOCOL_QDEBUG
        qDebug()<<"buffer size:"<<this->bytesAvailable();
#endif
        if(this->m_readyReadVersion)
        {
            if(this->bytesAvailable()<PROTECT_VERSION_DATA_SIZE)
            {
                break;
            }
            emit receivedVersion(this->read(PROTECT_VERSION_DATA_SIZE));
            this->m_readyReadVersion = false;
        }
        else
        {
            if(this->m_readyReadSize)
            {
                if(bytesAvailable() < 4)
                {
                    break;
                }
                if(-1==this->read(static_cast<char*>(static_cast<void*>(&m_packetSize)), 4))
                {
#ifdef EREMOTEPROTOCOL_QDEBUG
                    qCritical()<<"读取数据错误";
#endif
                    break;
                }
#ifdef EREMOTEPROTOCOL_QDEBUG
                qDebug()<<"待读取数据包大小:"<<m_packetSize;
#endif
                // TODO: 判断m_packetSize是否在合理范围内，如果不合理，应进行异常处理
                if(m_packet.size()<m_packetSize)
                {
                    m_packet.resize(m_packetSize);
                }
                this->m_readPacketSize = 0;
                this->m_readyReadSize = false;
            }
            else
            {
                int readSize = static_cast<int>(this->read(this->m_packet.data()+this->m_readPacketSize
                                            , this->m_packetSize-this->m_readPacketSize));
                if(-1==readSize)
                {
#ifdef EREMOTEPROTOCOL_QDEBUG
                    qCritical()<<"读取数据错误";
#endif
                    break;
                }
                this->m_readPacketSize += readSize;
#ifdef EREMOTEPROTOCOL_QDEBUG
                qDebug()<<QString("取数据包:%1/%2").arg(m_readPacketSize).arg(m_packetSize);
#endif
                if(this->m_readPacketSize == this->m_packetSize)
                {
                    QByteArray data = m_packet.left(m_packetSize);
                    parsePacket(data);
                    this->m_readyReadSize = true;
                }
            }
        }
    }
}

void RemoteTcpSocket::parsePacket(QByteArray &)
{

}
